package com.ghp.common.utils;


import cn.hutool.core.lang.UUID;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;

/**
 * @author ghp
 * @date 2023/3/21
 * @title Jwt工具类
 * @description
 */
public class JwtGeneratorUtils {

    private JwtGeneratorUtils() {
    }

    /**
     * Jwt 有效期，单位 ms
     */
    private static final Long DEFAULT_JWT_TTL = 6 * 60 * 60 * 1000L;

    /**
     * 设置私钥明文
     */
    private static final String JWT_KEY = "ghp";

    /**
     * JWT签发人
     */
    private static final String JWT_SIGNER = "ghp";

    /**
     * 默认采用的加密算法为 AES（此外还可以是MD4，DES等）
     */
    private static final String DEFAULT_ENCRYPTION_ALGORITHM = "AES";

    /**
     * 创建Jwt，采用默认的有效期
     *
     * @param subject jwt中要存放的数据（json格式）
     * @return
     */
    public static String createJWT(String subject) {
        JwtBuilder builder = getJwtBuilder(subject, DEFAULT_JWT_TTL);
        return builder.compact();
    }

    /**
     * 创建Jwt，自定义有效期
     *
     * @param subject   jwt中要存放的数据（json格式）
     * @param ttlMillis jwt有效期,单位秒
     * @return
     */
    public static String createJWT(String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis);
        return builder.compact();
    }

    /**
     * 解析Jwt
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generateSecretKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

    /**
     * 生成加密后的秘钥 secretKey
     *
     * @return
     */
    private static SecretKey generateSecretKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtGeneratorUtils.JWT_KEY);
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, DEFAULT_ENCRYPTION_ALGORITHM);
    }

    /**
     * 构建Jwt
     *
     * @param subject   jwt中要存放的数据（json格式）
     * @param ttlMillis jwt有效期，单位是秒
     * @return
     */
    private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis) {
        // 采用HS256签名认证算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 生成私钥
        SecretKey secretKey = generateSecretKey();
        // 设置jwt有效期
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        // 构建jwt并返回
        return Jwts.builder()
                // 唯一的ID
                .setId(UUID.fastUUID().toString(true))
                // 主题  可以是JSON数据
                .setSubject(subject)
                // 签发者
                .setIssuer(JWT_SIGNER)
                // 签发时间
                .setIssuedAt(now)
                // 使用HS256对称加密算法签名, 第二个参数为秘钥
                .signWith(signatureAlgorithm, secretKey)
                // 设置超时时间
                .setExpiration(expDate);
    }


    /**
     * 用于测试，无实际作用，可删除
     */
    public static void main(String[] args) throws Exception {
        // 生成JWT
        String jwt = createJWT("123");
        System.out.println("jwt = " + jwt);
        // 解析JWT
        Claims claims = parseJWT(jwt);
        System.out.println(claims);
    }


}